home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-10 | 11.9 KB | 436 lines | [TEXT/PJMM] |
- unit WEObjects;
-
- { WASTE PROJECT: }
- { Embedded Objects }
-
- { Copyright © 1993-1994 Marco Piovanelli }
- { All Rights Reserved }
-
- interface
- uses
- WEInterface;
-
- const
-
- { result codes }
-
-
- { values for WEInstallObjectHandler handlerSelector parameter }
-
- weNewHandler = 'new ';
- weDisposeHandler = 'free';
- weDrawHandler = 'draw';
- weClickHandler = 'clik';
- weCursorHandler = 'curs';
-
- type
-
- { A WESoup record is a static description of an object embedded in the text }
- { the 'SOUP' flavor is just a collection of WESoup records, each followed }
- { by the corresponding object data. }
- { This flavor complements the standard TEXT/styl pair. }
-
- WESoup = record
- soupOffset: LongInt; { insertion offset for this object }
- soupType: OSType; { 4-letter tag identifying object type }
- soupReserved1: LongInt; { reserved for future use; set to zero }
- soupDataSize: Size; { size of object data (following this record) }
- soupSize: Point; { object height and width, in pixels }
- soupReserved2: LongInt; { reserved for future use; set to zero }
- { actual object data follows }
- end; { WESoup }
- WESoupPtr = ^WESoup;
- WESoupHandle = ^WESoupPtr;
-
- { A WEObjectDesc record is used to keep track of embedded objects in memory. }
- { Notice that the first two fields are an AEDesc record, i.e. "tagged data" }
-
- WEObjectDesc = record
- objectType: OSType; { 4-letter tag identifying object type }
- objectDataHandle: Handle; { handle to object data }
- objectSize: Point; { object height and width, in pixels }
- objectIndex: Integer; { precalculated index into object handler table }
- objectOwner: WEHandle; { handle to owner WE instance }
- objectRefCon: LongInt; { free for use by object handlers }
- end; { WEObjectDesc }
- WEObjectDescPtr = ^WEObjectDesc;
- WEObjectDescHandle = ^WEObjectDescPtr;
-
- { embedded object functions for use by the client application }
-
- function WEInstallObjectHandler (objectType: OSType;
- handlerSelector: OSType;
- handler: ProcPtr): OSErr;
-
- { accessor functions for use by object handlers }
-
- function WEGetObjectType (hObjectDesc: WEObjectDescHandle): OSType;
- function WEGetObjectDataHandle (hObjectDesc: WEObjectDescHandle): Handle;
- function WEGetObjectSize (hObjectDesc: WEObjectDescHandle): Point;
- function WEGetObjectOwner (hObjectDesc: WEObjectDescHandle): WEHandle;
- function WEGetObjectRefCon (hObjectDesc: WEObjectDescHandle): LongInt;
- procedure WESetObjectRefCon (hObjectDesc: WEObjectDescHandle;
- refCon: LongInt);
-
- { object management function for WASTE internal use }
-
- function _WENewObject (objectType: OSType;
- objectDataHandle: Handle;
- hWE: WEHandle;
- var hObjectDesc: WEObjectDescHandle): OSErr;
- function _WEFreeObject (hObjectDesc: WEObjectDescHandle): OSErr;
- function _WEDrawObject (hObjectDesc: WEObjectDescHandle): OSErr;
- function _WEClickObject (hitPt: Point;
- modifiers: Integer;
- clickTime: LongInt;
- hObjectDesc: WEObjectDescHandle): Boolean;
- function _WEGetIndObjectType (index: Integer;
- var objectType: OSType): OSErr;
-
- implementation
-
- const
-
- kUnknownObjectType = -1; { specifies an object type for which no handlers are installed }
- kDefaultObjectSize = $00200020; { default object size (32x32 pixels) }
-
- type
-
- WEOHTableElement = record
- objectType: OSType; { 4-letter tag identifying object type }
- newHandler: ProcPtr;
- freeHandler: ProcPtr;
- drawHandler: ProcPtr;
- clickHandler: ProcPtr;
- cursorHandler: ProcPtr;
- end; { WEOHTableElement }
- WEOHTableElementPtr = ^WEOHTableElement;
-
- WEOHTable = array[0..0] of WEOHTableElement;
- WEOHTablePtr = ^WEOHTable;
- WEOHTableHandle = ^WEOHTablePtr;
-
- var
-
- { static variables }
-
- sHandlerTable: WEOHTableHandle;
- sHandlerCount: Integer;
-
- function WEGetObjectType (hObjectDesc: WEObjectDescHandle): OSType;
- begin
- WEGetObjectType := hObjectDesc^^.objectType;
- end; { WEGetObjectType }
-
- function WEGetObjectDataHandle (hObjectDesc: WEObjectDescHandle): Handle;
- begin
- WEGetObjectDataHandle := hObjectDesc^^.objectDataHandle;
- end; { WEGetObjectDataHandle }
-
- function WEGetObjectSize (hObjectDesc: WEObjectDescHandle): Point;
- begin
- WEGetObjectSize := hObjectDesc^^.objectSize;
- end; { WEGetObjectSize }
-
- function WEGetObjectOwner (hObjectDesc: WEObjectDescHandle): WEHandle;
- begin
- WEGetObjectOwner := hObjectDesc^^.objectOwner;
- end; { WEGetObjectOwner }
-
- function WEGetObjectRefCon (hObjectDesc: WEObjectDescHandle): LongInt;
- begin
- WEGetObjectRefCon := hObjectDesc^^.objectRefCon;
- end; { WEGetObjectRefCon }
-
- procedure WESetObjectRefCon (hObjectDesc: WEObjectDescHandle;
- refCon: LongInt);
- begin
- hObjectDesc^^.objectRefCon := refCon;
- end; { WESetObjectRefCon }
-
- function _WELookupObjectType (objectType: OSType): Integer;
-
- { look for a WEOHTableElement record for the specified object kind }
- { in our private object handler table }
-
- var
- pTable: WEOHTablePtr;
- index: Integer;
- begin
-
- { assume no handlers have been installed for this object type }
- _WELookupObjectType := kUnknownObjectType;
-
- { do nothing if the Object Handler Table has not been inited yet }
- if (sHandlerTable = nil) then
- Exit(_WELookupObjectType);
-
- { scan the Object Handler Table looking for a type match }
- pTable := sHandlerTable^;
- for index := sHandlerCount - 1 downto 0 do
- if (pTable^[index].objectType = objectType) then
- begin
- _WELookupObjectType := index;
- Exit(_WELookupObjectType);
- end;
-
- end; { _WELookupObjectType }
-
- function _WEGetIndObjectType (index: Integer;
- var objectType: OSType): OSErr;
- begin
- _WEGetIndObjectType := noErr;
- objectType := OSType(0);
-
- if (index >= 0) and (index < sHandlerCount) then
- objectType := sHandlerTable^^[index].objectType
- else
- _WEGetIndObjectType := weUnknownObjectTypeErr;
- end; { _WEGetIndObjectType }
-
- function CallNewHandler (var defaultObjectSize: Point;
- hObjectDesc: WEObjectDescHandle;
- newHandler: ProcPtr): OSErr;
- inline
- $205F, { movea.l (sp)+, a0 }
- $4E90; { jsr (a0) }
-
- function _WENewObject (objectType: OSType;
- objectDataHandle: Handle;
- hWE: WEHandle;
- var hObjectDesc: WEObjectDescHandle): OSErr;
- label
- 1;
- var
- pDesc: WEObjectDescPtr;
- index: Integer;
- err: OSErr;
- begin
- _WENewObject := noErr;
- hObjectDesc := nil;
-
- { look up the specified object type in the handler table }
- index := _WELookupObjectType(objectType);
-
- { create a new relocatable block to hold the object descriptor }
- err := _WEAllocate(SizeOf(WEObjectDesc), kAllocClear, hObjectDesc);
- if (err <> noErr) then
- goto 1;
-
- { lock it down }
- HLock(Handle(hObjectDesc));
- pDesc := hObjectDesc^;
-
- { fill in the object descriptor }
- pDesc^.objectType := objectType;
- pDesc^.objectDataHandle := objectDataHandle;
- pDesc^.objectSize := Point(kDefaultObjectSize);
- pDesc^.objectIndex := index;
- pDesc^.objectOwner := hWE;
-
- if (index >= 0) then
- with sHandlerTable^^[index] do
-
- { call the new handler, if any }
- if (newHandler <> nil) then
- begin
- err := CallNewHandler(pDesc^.objectSize, hObjectDesc, newHandler);
- if (err <> noErr) then
- begin
- _WEForgetHandle(hObjectDesc);
- goto 1;
- end;
- end;
-
- { unlock the object descriptor }
- HUnlock(Handle(hObjectDesc));
-
- { clear result code }
- err := noErr;
-
- 1:
- { return result code }
- _WENewObject := err;
-
- end; { _WENewObject }
-
- function CallFreeHandler (hObjectDesc: WEObjectDescHandle;
- freeHandler: ProcPtr): OSErr;
- inline
- $205F, { movea.l (sp)+, a0 }
- $4E90; { jsr (a0) }
-
- function _WEFreeObject (hObjectDesc: WEObjectDescHandle): OSErr;
- var
- pDesc: WEObjectDescPtr;
- begin
- _WEFreeObject := noErr;
-
- { sanity check: do nothing if we have a null descriptor handle }
- if (hObjectDesc = nil) then
- begin
- _WEFreeObject := nilHandleErr;
- Exit(_WEFreeObject);
- end;
-
- { lock the descriptor record }
- HLock(Handle(hObjectDesc));
- pDesc := hObjectDesc^;
-
- if (pDesc^.objectIndex >= 0) then
- with sHandlerTable^^[pDesc^.objectIndex] do
- begin
-
- {$IFC WASTE_DEBUG}
- { sanity check: make sure object kind matches handler kind }
- _WEAssert(pDesc^.objectType = objectType, 'Object Type Mismatch');
- {$ENDC}
-
- { call the dispose handler, if any }
- if (freeHandler <> nil) then
- begin
- _WEFreeObject := CallFreeHandler(hObjectDesc, freeHandler);
- pDesc^.objectDataHandle := nil;
- end;
- end;
-
- { if object kind is unknown or there's no custom dispose handler, use DisposeHandle }
- _WEForgetHandle(pDesc^.objectDataHandle);
-
- { finally, dispose of the object descriptor itself }
- DisposeHandle(Handle(hObjectDesc));
-
- end; { _WEFreeObject }
-
- function CallDrawHandler (destRect: Rect;
- hObjectDesc: WEObjectDescHandle;
- drawHandler: ProcPtr): OSErr;
- inline
- $205F, { movea.l (sp)+, a0 }
- $4E90; { jsr (a0) }
-
- function _WEDrawObject (hObjectDesc: WEObjectDescHandle): OSErr;
- var
- pDesc: WEObjectDescPtr;
- thePen: Point;
- destRect: Rect;
- begin
- _WEDrawObject := noErr;
-
- { the pen has already been set to the bottom left of the rectangle to draw }
- GetPen(thePen);
-
- pDesc := hObjectDesc^;
-
- { calculate the destination rectangle }
- destRect.top := thePen.v - pDesc^.objectSize.v;
- destRect.left := thePen.h;
- destRect.bottom := thePen.v;
- destRect.right := thePen.h + pDesc^.objectSize.h;
-
- { calculate the new pen position }
- thePen.h := thePen.h + pDesc^.objectSize.h;
-
- if (pDesc^.objectIndex >= 0) then
- with sHandlerTable^^[pDesc^.objectIndex] do
- begin
-
- {$IFC WASTE_DEBUG}
- { sanity check: make sure object kind matches handler kind }
- _WEAssert(pDesc^.objectType = objectType, 'Object Type Mismatch');
- {$ENDC}
-
- { call the drawing handler, if any }
- if (drawHandler <> nil) then
- _WEDrawObject := CallDrawHandler(destRect, hObjectDesc, drawHandler);
-
- end;
-
- { advance the pen position }
- MoveTo(thePen.h, thePen.v);
-
- end; { _WEDrawObject }
-
- function CallClickHandler (hitPt: Point;
- modifiers: Integer;
- clickTime: LongInt;
- hObjectDesc: WEObjectDescHandle;
- clickHandler: ProcPtr): Boolean;
- inline
- $205F, { movea.l (sp)+, a0 }
- $4E90; { jsr (a0) }
-
- function _WEClickObject (hitPt: Point;
- modifiers: Integer;
- clickTime: LongInt;
- hObjectDesc: WEObjectDescHandle): Boolean;
- var
- pDesc: WEObjectDescPtr;
- begin
- _WEClickObject := false; { assume we won't intercept this click }
- pDesc := hObjectDesc^;
-
- if (pDesc^.objectIndex >= 0) then
- with sHandlerTable^^[pDesc^.objectIndex] do
- begin
-
- {$IFC WASTE_DEBUG}
- { sanity check: make sure object kind matches handler kind }
- _WEAssert(pDesc^.objectType = objectType, 'Object Type Mismatch');
- {$ENDC}
-
- { call the click handler, if any }
- if (clickHandler <> nil) then
- _WEClickObject := CallClickHandler(hitPt, modifiers, clickTime, hObjectDesc, clickHandler);
-
- end;
- end; { _WEClickObject }
-
- function WEInstallObjectHandler (objectType: OSType;
- handlerSelector: OSType;
- handler: ProcPtr): OSErr;
- label
- 1;
- var
- index: Integer;
- element: WEOHTableElement;
- err: OSErr;
- begin
-
- { create the handler table, if it doesn't exist }
- if (sHandlerTable = nil) then
- begin
- err := %_NewHandle(0, Handle(sHandlerTable));
- if (err <> noErr) then
- goto 1;
- end;
-
- { look for an object handler record for the specified object type }
- index := _WELookupObjectType(objectType);
-
- if (index = kUnknownObjectType) then
- begin
-
- { previously unknown object kind: add a new element to the handler table }
- _WEBlockClr(@element, SizeOf(element));
- element.objectType := objectType;
- index := sHandlerCount;
- err := _WEInsertSlot(sHandlerTable, @element, index, SizeOf(element));
- if (err <> noErr) then
- goto 1;
-
- { increment handler count }
- sHandlerCount := index + 1;
-
- end;
-
- { install the handler }
- err := _WESetField(_WEObjectHandlerSelectorTable, handlerSelector, @handler, @sHandlerTable^^[index]);
-
- 1:
- { return result code }
- WEInstallObjectHandler := err;
-
- end; { WEInstallObjectHandler }
-
- end.